home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ifp / part07 < prev    next >
Encoding:
Text File  |  1987-07-06  |  55.6 KB  |  2,033 lines

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i040: Interpreted Functional Programming lanuage, Part 07/07
  5. Message-ID: <580@uunet.UU.NET>
  6. Date: 7 Jul 87 23:23:10 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2022
  9. Approved: rs@uunet.uu.net
  10.  
  11. Mod.sources: Volume 10, Number 40
  12. Submitted by: robison@b.cs.uiuc.edu (Arch Robison)
  13. Archive-name: ifp/Part07
  14.  
  15. #! /bin/sh
  16. # This is a shell archive, meaning:
  17. # 1. Remove everything above the #! /bin/sh line.
  18. # 2. Save the resulting text in a file.
  19. # 3. Execute the file with /bin/sh.
  20. # The following files will be created:
  21. #    interp/outfun.c
  22. #    interp/outob.c
  23. #    interp/stats.c
  24. #    interp/stats.h
  25. #    interp/string.c
  26. #    interp/string.h
  27. #    interp/struct.h
  28. #    interp/trace.c
  29. #    interp/umax.h
  30. #    interp/xdef.c
  31. export PATH; PATH=/bin:$PATH
  32. mkdir interp
  33. if test -f 'interp/outfun.c'
  34. then
  35.     echo shar: over-writing existing file "'interp/outfun.c'"
  36. fi
  37. cat << \SHAR_EOF > 'interp/outfun.c'
  38.  
  39. /****** outfun.c ******************************************************/
  40. /**                                                                  **/
  41. /**                    University of Illinois                        **/
  42. /**                                                                  **/
  43. /**                Department of Computer Science                    **/
  44. /**                                                                  **/
  45. /**   Tool: IFP                         Version: 0.5                 **/
  46. /**                                                                  **/
  47. /**   Author:  Arch D. Robison          Date: June 30, 1985          **/
  48. /**                                                                  **/
  49. /**   Revised by: Arch D. Robison       Date:  Dec 12, 1985          **/
  50. /**                                                                  **/
  51. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  52. /**                            Prof. W. J. Kubitz                    **/
  53. /**                                                                  **/
  54. /**                                                                  **/
  55. /**------------------------------------------------------------------**/
  56. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  57. /**                       All Rights Reserved.                       **/
  58. /**********************************************************************/
  59.  
  60.  
  61. #include <stdio.h>
  62. #include <ctype.h>
  63. #include "struct.h"
  64. #include "node.h"
  65.  
  66. /*
  67.  * OutLongNode - internal to OutNode
  68.  */
  69. void OutLongNode (N)
  70.    register NodePtr N;
  71.    {
  72.       if (N->NodeParent != NULL) {
  73.      OutLongNode (N->NodeParent);
  74.      printf ("/");
  75.      OutString (N->NodeName);
  76.       }
  77.    }
  78.  
  79. /*
  80.  * OutNode
  81.  *
  82.  * Output a node in UNIX path format.  
  83.  * Abbreviate if it is in the current directory.
  84.  */
  85. void OutNode (N)
  86.    register NodePtr N;
  87.    {
  88.       register NodePtr M;
  89.       extern boolean LongPathFlag;
  90.  
  91.       if (N == NULL) printf ("(NULL NODE)");
  92.       else {
  93.      if (!LongPathFlag && NULL != (M = FindNode (CurWorkDir,N->NodeName)) &&
  94.                   (M->NodeType == IMPORT || M->NodeType == DEF)) 
  95.         OutString (N->NodeName);
  96.      else OutLongNode (N);
  97.       }
  98.    }
  99.  
  100. /*
  101.  * OutForm
  102.  * 
  103.  * Print a functional form and its parameters.
  104.  *
  105.  * Input
  106.  *      N = pointer to form node
  107.  *      P = pointer to parameter list
  108.  *      Depth = depth to print function (ellipses used at that depth)
  109.  */
  110. void OutForm (N,P,Depth)
  111.    register NodePtr N;
  112.    ListPtr P;
  113.    int Depth;
  114.    {
  115.       long L;
  116.       register FormEntry *T;
  117.  
  118.       L = ListLength (P);
  119.  
  120.       for (T=FormTable; T<ArrayEnd(FormTable); T++) 
  121.      if (T->FormNode == N) {
  122.         switch (T-FormTable) {
  123.  
  124.            case NODE_Comp:
  125.           while (P!=NULL) {
  126.             OutFun (&P->Val,Depth);
  127.             if (NULL != (P=P->Next)) printf ("|");
  128.           }
  129.           break;
  130.  
  131.            case NODE_Cons:
  132.           printf ("[");
  133.           while (P!=NULL) {
  134.              OutFun (&P->Val,Depth);
  135.              if (NULL != (P=P->Next)) printf (",");       
  136.           }
  137.           printf ("]");
  138.           break;
  139.  
  140.            case NODE_RInsert:
  141.            case NODE_Filter:
  142.            case NODE_Each:
  143.           printf ("%s ",T->FormInPrefix); 
  144.           OutFun (&P->Val,Depth);
  145.           printf (" END");
  146.           break;
  147.  
  148.            case NODE_If:
  149.           printf ("IF ");    OutFun (&P->Val,Depth);
  150.           printf (" THEN "); OutFun (&(P=P->Next)->Val,Depth);
  151.           printf (" ELSE "); OutFun (&P->Next->Val,Depth);
  152.           printf (" END"); 
  153.           break;
  154.    
  155.            case NODE_C: 
  156.           if (!L) {
  157.              printf ("?");
  158.              break;
  159.           } 
  160.           /* else drop through */
  161. #if FETCH
  162.            case NODE_Fetch:
  163. #endif
  164.            case NODE_Out: 
  165.           printf ("%s",T->FormInPrefix); OutObject (&P->Val);
  166.           break;
  167.  
  168.            case NODE_Sel:
  169.           if (P->Val.Int >= 0) printf ("%d",P->Val.Int);
  170.           else printf ("%dr",-P->Val.Int);
  171.           break;
  172.  
  173.            case NODE_While:
  174.           printf ("WHILE "); OutFun (&P->Val,Depth);
  175.           printf (" DO ");   OutFun (&P->Next->Val,Depth);
  176.           printf (" END");
  177.           break;
  178. #if XDEF
  179.            case NODE_XDef: {
  180.           extern void OutLHS ();
  181.           printf ("{");    OutLHS (&P->Val);
  182.           printf (" := "); OutFun (&P->Next->Val,Depth); 
  183.           printf ("} ");
  184.           OutFun (&P->Next->Next->Val,Depth); 
  185.           break;
  186.            }
  187. #endif
  188.         }
  189.         return;
  190.      }
  191.  
  192.       printf ("(");
  193.       OutNode (N); 
  194.       for (; P != NULL; P=P->Next) {    
  195.      printf (" ");
  196.      OutObject (&P->Val);
  197.       }
  198.       printf (")");
  199.    }
  200.  
  201.  
  202. /*
  203.  * OutFun
  204.  *
  205.  * Print function *F. *F may be linked if it was unlinked.
  206.  *
  207.  * The possible representations for the function are described
  208.  * in the comments for "Apply" in apply.c.
  209.  *
  210.  * Input
  211.  *      *F = function
  212.  *      Depth = depth to print function, 0 = "..."
  213.  *
  214.  * Output
  215.  *      *F = may be linked function
  216.  */
  217. void OutFun (F,Depth)
  218.    register ObjectPtr F;
  219.    int Depth;
  220.    {
  221.       register ListPtr P;
  222.  
  223.       if (SysStop > 1) return;
  224.  
  225.       if (F == NULL) printf ("(null)");          /* Internal error */
  226.       else if (--Depth < 0) printf ("..");
  227.       else 
  228.  
  229.      switch (F->Tag) {
  230.  
  231.         default:
  232.            printf ("(tag = %d)",F->Tag);     /* Internal error */
  233.            break;
  234.  
  235.         case LIST:
  236.            P = F->List;
  237.            if (P == NULL) printf ("()");
  238.            else
  239.  
  240.           switch (P->Val.Tag) {
  241.     
  242.              case LIST:   /* unlinked form */
  243.             LinkPath (&P->Val,DEF);
  244.             if (P->Val.Tag!=NODE||P->Val.Node->NodeType!=DEF) {
  245.                printf ("(");
  246.                OutObject (&P->Val);
  247.                for (; P != NULL; P=P->Next) {    
  248.                   printf (" ");
  249.                   OutObject (&P->Val);
  250.                }
  251.                printf (")");
  252.                return;
  253.             } /* else drop down to case NODE */
  254.  
  255.              case NODE:   /* linked form */
  256.             OutForm (P->Val.Node,P->Next,Depth);
  257.             return;
  258.  
  259.              case STRING:
  260.             LinkPath (F,DEF);
  261.             if (F->Tag == NODE) break; /* drop down to case NODE */
  262.  
  263.              default: /* unlinked function or internal error */
  264.             for (; P!=NULL; P=P->Next) {
  265.                printf ("/");
  266.                OutObject (&P->Val);
  267.             }
  268.             return;
  269.           }
  270.  
  271.         case NODE:
  272.            OutNode (F->Node);
  273.            break;
  274.  
  275.         case STRING:
  276.            OutString (F->String);
  277.            break;
  278.      }
  279.    }
  280.  
  281.  
  282. /******************************* end of outfun.c ******************************/
  283.  
  284. SHAR_EOF
  285. if test -f 'interp/outob.c'
  286. then
  287.     echo shar: over-writing existing file "'interp/outob.c'"
  288. fi
  289. cat << \SHAR_EOF > 'interp/outob.c'
  290.  
  291. /****** out.c *********************************************************/
  292. /**                                                                  **/
  293. /**                    University of Illinois                        **/
  294. /**                                                                  **/
  295. /**                Department of Computer Science                    **/
  296. /**                                                                  **/
  297. /**   Tool: IFP                         Version: 0.5                 **/
  298. /**                                                                  **/
  299. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  300. /**                                                                  **/
  301. /**   Revised by: Arch D. Robison       Date:   Feb 8, 1987          **/
  302. /**                                                                  **/
  303. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  304. /**                            Prof. W. J. Kubitz                    **/
  305. /**                                                                  **/
  306. /**                                                                  **/
  307. /**------------------------------------------------------------------**/
  308. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  309. /**                       All Rights Reserved.                       **/
  310. /**********************************************************************/
  311.  
  312.  
  313. #include <stdio.h>
  314. #include <ctype.h>
  315. #include "struct.h"
  316. #include "string.h"
  317.  
  318. #define BerkMode 0
  319.  
  320. #define INDENT 3
  321.  
  322. /*
  323.  * OutIndent
  324.  *
  325.  * Indent N places
  326.  */
  327. void OutIndent (N)
  328.    int N;
  329.    {
  330.       for (; N >= 8; N-=8) printf ("\t");
  331.       while (--N >=0) printf (" ");
  332.    }
  333.  
  334. /*
  335.  * QuoteCheck
  336.  *
  337.  * Check if string should be quoted.
  338.  *
  339.  * Input
  340.  *      S = string
  341.  * Output
  342.  *      result = quote character ('\0','\'', or '\"');
  343.  */
  344. char QuoteCheck (S)
  345.    StrPtr S;
  346.    {
  347.       CharPtr U;
  348.       char Buf[256];
  349.       boolean Single=0,Double=0,Quote=0;
  350.       register char *T;
  351.  
  352.       if (S==NULL) return ('\"');
  353.       else {
  354.      CPInit (&U,&S);
  355.      if (CPRead (&U,Buf,sizeof (Buf))) {
  356.         if (Buf [1] == '\0' && (Buf[0]=='f' || Buf[0]=='t' || Buf[0]=='?'))
  357.            return '\"';
  358.         do
  359.            for (T = Buf; *T; T++)
  360.           if (!isalpha (*T)) {
  361.              Quote=1;
  362.              if (*T == '\'') Single = 1;
  363.              if (*T == '\"') Double = 1;
  364.           }
  365.         while (CPRead (&U,Buf,sizeof (Buf)));
  366.      }
  367.  
  368.      if (!Quote) return '\0';
  369.      else if (Single) return '\"';
  370.      else if (Double) return '\'';
  371.      else return '\"';             /* Should be something else */
  372.       }
  373.    }
  374.  
  375. /*
  376.  * OutString
  377.  *
  378.  * Output a string.
  379.  */
  380. void OutString (S)
  381.    StrPtr S;
  382.    {
  383.       char Buf[256];
  384.       CharPtr U;
  385.  
  386.       if ((Debug & DebugRef) && S != NULL) printf ("[%d]",S->SRef);
  387.       CPInit (&U,&S);
  388.       while (CPRead (&U,Buf,sizeof (Buf))) printf ("%s",Buf);
  389.    }
  390.  
  391. /*
  392.  * OutList
  393.  *
  394.  * Input
  395.  *      P = list to output
  396.  */
  397. void OutList (P)
  398.    register ListPtr P;
  399.    {
  400.       printf ("<");
  401.       if (P!=NIL)
  402.      while (1) {
  403.         if (Debug & DebugRef) printf ("{%d}",P->LRef + (1 - LRefOne));
  404.         OutObject (& P->Val);
  405.         if ((P=P->Next) == NULL) break; 
  406.         else printf (",");
  407.      }
  408.       printf (">");
  409.    }
  410.  
  411.  
  412. /*
  413.  * OutObject
  414.  *
  415.  * Output an object
  416.  *
  417.  * No reference counts change.
  418.  */
  419. void OutObject (X)
  420.    ObjectPtr X;
  421.    {
  422.       if (SysStop > 1) return;
  423.       else if (X == NULL) printf ("(NULL)");
  424.       else
  425.      switch (X->Tag) {
  426.         case BOTTOM: printf ("?"); break;
  427.         case BOOLEAN:
  428.            switch (X->Bool) {
  429.           case 0: printf (BerkMode ? "F" : "f"); break;
  430.           case 1: printf (BerkMode ? "T" : "t"); break;
  431.           default: printf ("(BOOLEAN %d)",X->Bool); break;
  432.            }
  433.            break;
  434.         case INT:
  435.            printf ("%ld",X->Int);
  436.            break;
  437.  
  438.         case FLOAT:
  439.            printf ("%g",X->Float);
  440.            break;
  441.  
  442.         case LIST:
  443.            OutList (X->List);
  444.            break;
  445.  
  446.         case STRING: {
  447.            register char Q;
  448.            Q = QuoteCheck (X->String);
  449.            if (Q) printf ("%c",Q);
  450.            OutString (X->String);
  451.            if (Q) printf ("%c",Q);
  452.         }  break;
  453.  
  454.         case NODE:
  455.            OutNode (X->Node);
  456.            break;
  457.         default:
  458.            printf ("(tag = %d)",X->Tag);
  459.            break;
  460.      }
  461.    }
  462.  
  463. #define LineLength 80
  464.  
  465. /*
  466.  * OutLength
  467.  *
  468.  * Compute approximate number of characters required to output an object.
  469.  * The count is stopped prematurely if it goes over LineLength.
  470.  * 
  471.  * No reference counts change.
  472.  */
  473. private int OutLength (X,Limit)
  474.    ObjectPtr X;
  475.    int Limit;
  476.    {
  477.       register ListPtr P;
  478.       register int K;
  479.  
  480.       if (X == NULL) K = 6;     /* "(null)" */
  481.       else
  482.      switch (X->Tag) {
  483.  
  484.         case BOTTOM:
  485.         case BOOLEAN:
  486.            K = 1; /* "?","t","f" */
  487.            break;
  488.  
  489.         case INT:
  490.            K = 5;
  491.            break;
  492.  
  493.         case FLOAT:
  494.            K = 8;
  495.            break;
  496.  
  497.         case LIST:
  498.            K = 2;                                   /* <> */
  499.            for (P=X->List; P!=NULL && K <= Limit; P=P->Next) 
  500.           K += 1 + OutLength (&P->Val,Limit); /* 1 for space between */
  501.            break;
  502.  
  503.         case STRING:
  504.            K = 2 + LenStr (X->String);  /* "'...'" */
  505.            break;
  506.         default:
  507.            K=0;
  508.            break;
  509.      }
  510.       return K;
  511.    }
  512.  
  513. /*
  514.  * OutPretty
  515.  *
  516.  * Output an object with indented sublists
  517.  *
  518.  * No reference counts change.
  519.  */
  520. void OutPretty (X,Indent)
  521.    ObjectPtr X;
  522.    int Indent;
  523.    {
  524.       register ListPtr P;
  525.  
  526.       if (SysStop > 1) return;
  527.       OutIndent (Indent);
  528.       if (X == NULL) printf ("(null)");
  529.       else if (X->Tag != LIST) OutObject (X);
  530.       else {
  531.      if ((OutLength (X,LineLength) + Indent) > LineLength) {
  532.         printf ("<\n");
  533.         for (P = X->List; P!=NULL; P=P->Next)
  534.            OutPretty (&P->Val,Indent+INDENT);
  535.         OutIndent (Indent);
  536.         printf (">\n");
  537.         return;
  538.      } else OutList (X->List);
  539.       }
  540.       printf ("\n");
  541.    }
  542.  
  543.  
  544. /************************** end of outob.c **************************/
  545.  
  546. SHAR_EOF
  547. if test -f 'interp/stats.c'
  548. then
  549.     echo shar: over-writing existing file "'interp/stats.c'"
  550. fi
  551. cat << \SHAR_EOF > 'interp/stats.c'
  552.  
  553. /****** stats.c *******************************************************/
  554. /**                                                                  **/
  555. /**                    University of Illinois                        **/
  556. /**                                                                  **/
  557. /**                Department of Computer Science                    **/
  558. /**                                                                  **/
  559. /**   Tool: IFP                         Version: 0.5                 **/
  560. /**                                                                  **/
  561. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  562. /**                                                                  **/
  563. /**   Revised by: Arch D. Robison       Date:   Dec 8, 1985          **/
  564. /**                                                                  **/
  565. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  566. /**                            Prof. W. J. Kubitz                    **/
  567. /**                                                                  **/
  568. /**                                                                  **/
  569. /**------------------------------------------------------------------**/
  570. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  571. /**                       All Rights Reserved.                       **/
  572. /**********************************************************************/
  573.  
  574. /* Statistics collection routines */ 
  575.  
  576. #include "struct.h"
  577. #include "stats.h"
  578. #include <stdio.h>
  579.  
  580. #if STATS
  581.  
  582. long StatRecycle=0,StatFresh=0;
  583. long StatArg [MAXTAG+1];
  584. long Stat_Apply      [StatLimLen+1];
  585. long Stat_NewList    [StatLimLen+1];
  586. long Stat_DelLPtrIn  [StatLimLen+1];
  587. long Stat_DelLPtrOut [StatLimLen+1];
  588. long Stat_Construct  [StatLimLen+1];
  589. long Stat1Simple,Stat2Simple;
  590. long StatC = 0;
  591.  
  592. void StatConstant (InOut)
  593.    ObjectPtr InOut;
  594.    {
  595.       StatC++;
  596.    }
  597.  
  598. void StatConstruct (P)
  599.    ListPtr P;
  600.    {
  601.       register int N;
  602.       N = ListLength (P);
  603.       if (N >= StatLimLen) N = StatLimLen;
  604.       ++Stat_Construct[N];
  605.    }
  606.  
  607. void StatNewList (N)
  608.    long N;
  609.    {
  610.       StatFresh += N;
  611.       if (N > StatLimLen) N = StatLimLen;
  612.       ++Stat_NewList [N];
  613.    }
  614.  
  615. void StatDelLPtr (P)
  616.    register ListPtr P;
  617.    {
  618.       register int N;
  619.  
  620.       N = ListLength (P);
  621.       if (N >= StatLimLen) N = StatLimLen;
  622.  
  623.       ++Stat_DelLPtrIn [N];
  624.       for (N=0; P!=NULL; P=P->Next)
  625.      if (P->LRef > LRefOne || ++N >= StatLimLen) break; 
  626.       ++Stat_DelLPtrOut [N];
  627.    }
  628.  
  629. #define SCALAR ((1<<INT)|(1<<FLOAT)|(1<<BOOLEAN)|(1<<STRING))
  630.  
  631. void StatApply (InOut)
  632.    ObjectPtr InOut;
  633.    {
  634.       ListPtr P;
  635.       long L;
  636.  
  637.       StatArg [InOut->Tag] ++;
  638.       if (InOut->Tag == LIST) {
  639.      L = ListLength (InOut->List);
  640.      if (L > StatLimLen) L = StatLimLen;
  641.      Stat_Apply [L] ++;
  642.      if (L == 2) {
  643.         P = InOut->List;
  644.         if ((1<<P->Val.Tag) & SCALAR) Stat1Simple++;
  645.         if ((1<<P->Next->Val.Tag) & SCALAR) Stat2Simple++;
  646.      }
  647.       }
  648.    }
  649.  
  650.  
  651. /*
  652.  * ShowDist
  653.  */
  654. void ShowDist (Title,Dist)
  655.    char *Title;
  656.    long Dist[];
  657.    {
  658.       int k;
  659.       long S,Z;
  660.  
  661.       for (S=0, k=0; k<=StatLimLen; k++) S += Dist[k];
  662.  
  663.       printf ("   %s (total = %ld)\n      ",Title,S);
  664.       if (S) 
  665.      for (k=0; k<=StatLimLen; k++) {
  666.         Z = 1000 * Dist[k]/S;
  667.         printf ("%ld.%ld%% [%s%ld]   ",Z/10,Z%10,k==StatLimLen?">=":"",k);
  668.         Dist[k] = 0;
  669.      }
  670.       printf ("\n");
  671.    }
  672.  
  673. /*
  674.  * ShowStats
  675.  */
  676. void ShowStats ()
  677.    {
  678.       long Total;
  679.       int k;
  680.  
  681.       printf ("\n"); 
  682.       Total = StatRecycle + StatFresh;
  683.       printf ("Memory management\n");
  684.       printf ("   Total cells created = %ld\n",Total);
  685.       printf ("   Percent of cells recycled = %ld\n",
  686.           Total ? 100*StatRecycle/Total : 0L);
  687.       ShowDist ("New list length distribution",Stat_NewList);
  688.       StatRecycle = StatFresh = 0;
  689.       ShowDist ("Deleted list (total) length distribution",Stat_DelLPtrIn);
  690.       ShowDist ("Deleted list (partial) length distribution",Stat_DelLPtrOut);
  691.       ShowDist ("Constructor list length distribution",Stat_Construct);
  692.       printf ("\n");
  693.  
  694.       printf ("Constant function applications = %d\n",StatC);
  695.       StatC = 0;
  696.       printf ("\n");
  697.  
  698.       if (Stat_Apply [2]) {
  699.      Stat1Simple = 100 * Stat1Simple / Stat_Apply [2];
  700.      Stat2Simple = 100 * Stat2Simple / Stat_Apply [2];
  701.       }
  702.       if (StatArg[LIST])
  703.      for (k=0; k<=StatLimLen; k++)
  704.         Stat_Apply [k] = 100 * Stat_Apply [k] / StatArg[LIST];
  705.       Total = 0;
  706.       for (k=0; k<=MAXTAG; k++) Total += StatArg [k];
  707.       if (Total)
  708.      for (k=0; k<=MAXTAG; k++) StatArg [k] = 100 * StatArg [k] / Total;
  709.       printf ("\n");
  710.       printf ("Apply arguments (Total = %ld)\n",Total);
  711.       printf ("   Boolean = %ld, Int = %ld, Float = %ld, String = %ld\n",
  712.           StatArg[BOOLEAN],StatArg[INT],StatArg[FLOAT],StatArg[STRING]);
  713.       printf ("   List = %ld\n",StatArg[LIST]);
  714.       printf ("   ");
  715.       for (k=0; k<StatLimLen; k++) printf ("%ld [%ld], ",Stat_Apply [k],k);
  716.       printf ("%ld [>=%d]\n",Stat_Apply [StatLimLen],StatLimLen);
  717.       printf ("   Pair elements [scalar]<%ld,%ld>\n",Stat1Simple,Stat2Simple);
  718.       Stat1Simple = Stat2Simple = 0;
  719.       for (k=0; k<=StatLimLen; k++) Stat_NewList [k] = Stat_Apply[k] = 0;
  720.       for (k=0; k<=MAXTAG; k++) StatArg[k] = 0;
  721.    }
  722. #endif
  723.  
  724. /**************************** end of stats.c ****************************/
  725.  
  726. SHAR_EOF
  727. if test -f 'interp/stats.h'
  728. then
  729.     echo shar: over-writing existing file "'interp/stats.h'"
  730. fi
  731. cat << \SHAR_EOF > 'interp/stats.h'
  732.  
  733. /****** stats.h *******************************************************/
  734. /**                                                                  **/
  735. /**                    University of Illinois                        **/
  736. /**                                                                  **/
  737. /**                Department of Computer Science                    **/
  738. /**                                                                  **/
  739. /**   Tool: IFP                         Version: 0.5                 **/
  740. /**                                                                  **/
  741. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  742. /**                                                                  **/
  743. /**   Revised by: Arch D. Robison       Date:   Dec 8, 1985          **/
  744. /**                                                                  **/
  745. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  746. /**                            Prof. W. J. Kubitz                    **/
  747. /**                                                                  **/
  748. /**                                                                  **/
  749. /**------------------------------------------------------------------**/
  750. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  751. /**                       All Rights Reserved.                       **/
  752. /**********************************************************************/
  753.  
  754. /* 
  755.  * Defining STATS=1 causes interpreter to collect statistics. 
  756.  * Define STATS=0 for production work since statistics collection
  757.  * slows the interpreter.
  758.  */
  759. #define STATS 0
  760.       
  761. #if STATS
  762.  
  763. #define StatLimLen 5
  764. #define Stat(X) X
  765. extern long StatRecycle,StatFresh;
  766. extern long StatArg [];
  767. extern long Stat_Apply [];
  768. extern long Stat_NewList [];
  769. extern long Stat1Simple,Stat2Simple;
  770. extern void ShowStats();
  771. extern void StatApply(), StatConstruct(), StatConstant();
  772. extern void StatNewList(), StatDelLPtr();
  773. #else
  774.  
  775. #define Stat(X) 
  776.  
  777. #endif
  778.  
  779. /**************************** end of stats.h ****************************/
  780.  
  781. SHAR_EOF
  782. if test -f 'interp/string.c'
  783. then
  784.     echo shar: over-writing existing file "'interp/string.c'"
  785. fi
  786. cat << \SHAR_EOF > 'interp/string.c'
  787.  
  788. /****** string.c ******************************************************/
  789. /**                                                                  **/
  790. /**                    University of Illinois                        **/
  791. /**                                                                  **/
  792. /**                Department of Computer Science                    **/
  793. /**                                                                  **/
  794. /**   Tool: IFP                         Version: 0.5                 **/
  795. /**                                                                  **/
  796. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  797. /**                                                                  **/
  798. /**   Revised by: Arch D. Robison       Date:  Jan 20, 1987          **/
  799. /**                                                                  **/
  800. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  801. /**                            Prof. W. J. Kubitz                    **/
  802. /**                                                                  **/
  803. /**                                                                  **/
  804. /**------------------------------------------------------------------**/
  805. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  806. /**                       All Rights Reserved.                       **/
  807. /**********************************************************************/
  808.  
  809. #include <stdio.h>
  810. #include "struct.h"
  811. #include "node.h"
  812. #include "umax.h"
  813. #include "string.h"
  814.  
  815. /* Single character strings, CharString [0] = null string */
  816. StrPtr *CharString;  
  817.  
  818. /* Free string segments have SRef = 1 and are linked by StrNext link */
  819. StrPtr FreeString = NULL;
  820.  
  821. /*
  822.  * NewSCell
  823.  *
  824.  * return pointer to fresh string cell with SRef = 1 and StrNext = NULL.
  825.  *
  826.  * A SysError may occur, in which case the NULL pointer is returned.
  827.  */
  828. private StrPtr NewSCell ()
  829.    {
  830.       extern StrPtr AllocStrPage ();
  831.       register StrPtr S;
  832.  
  833.       semaphore_wait (SRefSemaphore);
  834.       if (FreeString != NULL || (FreeString = AllocStrPage ()) != NULL) {
  835.      S = FreeString;
  836.      FreeString = S->StrNext;
  837.      S->SRef = 1;
  838.      S->StrNext = NULL;
  839.       }
  840.       else {
  841.      SysError = NO_STR_FREE;
  842.      printf ("NO MORE STRING CELLS LEFT\n");
  843.      S = NULL;
  844.       }
  845.       semaphore_signal (SRefSemaphore);
  846.       return S;
  847.    }
  848.  
  849. /*
  850.  * CPInit
  851.  *
  852.  * Initialize a character pointer.
  853.  */
  854. void CPInit (U,S)
  855.    register CharPtr *U;
  856.    register StrPtr *S;
  857.    {
  858.       if ((U->CPSeg = *(U->CPStr = S)) == NULL) U->CPCount = 0;
  859.       else {
  860.      U->CPCount = StrHeadLen;
  861.      U->CPChar = (*S)->StrChar;
  862.       }
  863.    }
  864.  
  865. /*
  866.  * CPRead
  867.  *
  868.  * Read up to N-1 characters from and advance a character pointer.
  869.  * '\0' is returned as the last character of the string.
  870.  *
  871.  * Input
  872.  *     *U = character pointer
  873.  *     Buf = buffer into which to read characters
  874.  *     N-1 = number of characters to read
  875.  *
  876.  * Output
  877.  *      result = true if characters were read, 0 if end of string.
  878.  *      Buf = string of characters terminated by '\0'
  879.  */
  880. boolean CPRead (U,Buf,N)
  881.    register CharPtr *U;
  882.    register char *Buf;
  883.    register int N;
  884.    {
  885.       register char *S;
  886.       register int K;
  887.  
  888.       if (!U->CPCount && (NULL==U->CPSeg || NULL==U->CPSeg->StrNext) ||
  889.       !*(S = U->CPChar)) {
  890.  
  891.      *Buf = '\0';
  892.      return 0;
  893.  
  894.       } else {
  895.  
  896.      --N;
  897.      while (N > 0) {
  898.         K = U->CPCount;
  899.         if (K > N) K = N;
  900.         N -= K;
  901.         U->CPCount -= K;
  902.         while (--K >= 0) *Buf++ = *S++;
  903.         if (!U->CPCount) {
  904.            if (NULL == (U->CPSeg = U->CPSeg->StrNext)) break;
  905.            else {
  906.           U->CPCount = StrTailLen;
  907.           S = U->CPSeg->StrChar;
  908.            }
  909.         }
  910.      }
  911.      U->CPChar = S;
  912.      *Buf = '\0';
  913.      return 1;
  914.       }
  915.    }
  916.  
  917.  
  918. /*
  919.  * CPAppend
  920.  *
  921.  * Append a character to the end of a string.
  922.  *
  923.  * A SysError may occur.
  924.  */
  925. void CPAppend (U,C)
  926.    register CharPtr *U;
  927.    char C;
  928.    {
  929.       if (U->CPCount-- == 0)
  930.      if (C == '\0') return;
  931.      else {
  932.         register StrPtr S = NewSCell ();
  933.         if (SysError) return;
  934.         else {
  935.            U->CPChar = S->StrChar;
  936.            if (*U->CPStr == NULL) {
  937.           U->CPSeg = (*U->CPStr = S);           /* Append head segment */
  938.           U->CPCount = StrHeadLen-1;
  939.            } else {
  940.           U->CPSeg = (U->CPSeg->StrNext = S); /* Append tail segment */
  941.           U->CPCount = StrTailLen-1;
  942.            }
  943.         }
  944.      }
  945.       *U->CPChar++ = C;
  946.    }
  947.  
  948.  
  949. /*
  950.  * LenStr
  951.  *
  952.  * Find the length of a FP string
  953.  * 
  954.  * Input
  955.  *     S = IFP string
  956.  *
  957.  * Output
  958.  *    result = length of string in characters
  959.  */
  960. FPint LenStr (S)
  961.    register StrPtr S;
  962.    {
  963.       register int J = StrHeadLen;
  964.       register FPint K = 0;
  965.       register char *T;
  966.  
  967.       for (; S!=NULL; S = S->StrNext) {
  968.      for (T = S->StrChar; --J >= 0 && *T; T++) K++;
  969.      J = StrTailLen;
  970.       }
  971.       return K;
  972.    }
  973.  
  974.  
  975. /*
  976.  * DelSPtr
  977.  *
  978.  * Delete a string pointer: decrement reference count and remove string
  979.  * if reference count is zero.
  980.  */
  981. void DelSPtr (S)
  982.    register StrPtr S;
  983.    {
  984.       register StrPtr T;
  985.  
  986.       semaphore_wait (SRefSemaphore);
  987.       if (S != NULL && !-- S->SRef) {
  988.      for (T=S; T->StrChar[0]='\0', T->StrNext!=NULL; T=T->StrNext) continue;
  989.      T->StrNext = FreeString;
  990.      FreeString = S;
  991.       }
  992.       semaphore_signal (SRefSemaphore);
  993.    }
  994.  
  995. /*
  996.  * NewString
  997.  *
  998.  * Make a copy of a string.  The old string retains its reference count.
  999.  *
  1000.  * Input
  1001.  *    S = pointer to string
  1002.  *
  1003.  * Output
  1004.  *    result = pointer to new string
  1005.  *
  1006.  * A SysError may occur, in which case NULL is returned.
  1007.  */
  1008. private StrPtr NewString (S)
  1009.    register StrPtr S;
  1010.    {
  1011.       extern char *strncpy ();
  1012.       register StrPtr R,T;
  1013.  
  1014.       if (S == NULL) return NULL;
  1015.       R = T = NewSCell ();   /* R = root of copy */
  1016.       if (SysError) return NULL;
  1017.       (void) strncpy (T->StrChar,S->StrChar,StrHeadLen);
  1018.       while ((S=S->StrNext) != NULL) {
  1019.      T->StrNext = NewSCell ();
  1020.      T = T->StrNext;
  1021.      (void) strncpy (T->StrChar,S->StrChar,StrTailLen);
  1022.      if (SysError) {
  1023.         DelSPtr (R);   /* flush copy */
  1024.         return NULL;
  1025.      }
  1026.       }
  1027.       return R;
  1028.    }
  1029.  
  1030.  
  1031. /*
  1032.  * MakeString
  1033.  *
  1034.  * Make an IFP string from a C string.
  1035.  *
  1036.  * Input
  1037.  *      S = pointer to character array terminated by '\0'
  1038.  *
  1039.  * Output
  1040.  *      result = pointer to IFP (segmented) string
  1041.  *
  1042.  * A SysError may occur, in which case a NULL pointer is returned.
  1043.  */
  1044. StrPtr MakeString (S)
  1045.    char *S;
  1046.    {
  1047.       extern char *strncpy ();
  1048.       int L=strlen(S);
  1049.  
  1050.       if (L <= 0) return NULL;
  1051.       else {
  1052.          StrPtr R,T;
  1053.      int N = StrHeadLen;
  1054.      R = T = NewSCell ();                /* R = root of copy */
  1055.      if (SysError) return NULL;
  1056.      while (1) {
  1057.         (void) strncpy (T->StrChar,S,N);
  1058.         if ((L -= N) <= 0) return R;
  1059.         else {
  1060.            S += N;
  1061.            T->StrNext = NewSCell ();
  1062.            if (SysError) {
  1063.           DelSPtr (R);   /* flush copy */
  1064.           return NULL;
  1065.            }
  1066.            T = T->StrNext;
  1067.            N = StrTailLen;
  1068.         }
  1069.      }
  1070.       }
  1071.    }
  1072.  
  1073. /*
  1074.  * StrComp
  1075.  *
  1076.  * Compares two strings.  Returns P-Q
  1077.  */
  1078. int StrComp (P,Q)
  1079.    StrPtr P,Q;
  1080.    {
  1081.       register int Diff,Len;
  1082.       Len = StrHeadLen;
  1083.       while (1) {
  1084.      if (Q == NULL) return P!=NULL;
  1085.      else if (P == NULL) return -(Q!=NULL);
  1086.      else if (Diff = strncmp (P->StrChar,Q->StrChar,Len)) return Diff;
  1087.      else {
  1088.         Len = StrTailLen;
  1089.         P = P->StrNext;
  1090.         Q = Q->StrNext;
  1091.      }
  1092.       }
  1093.    }
  1094.  
  1095. /*
  1096.  * Make a copy of a non-null string pointer, incrementing the reference count.
  1097.  *
  1098.  * A SysError may occur, in in which case a NULL pointer is returned.
  1099.  */
  1100. StrPtr CopySPtr (S)
  1101.    StrPtr S;
  1102.    {
  1103.       semaphore_wait (SRefSemaphore);
  1104.       if (S != NULL && !++S->SRef) {
  1105.      S->SRef--;
  1106.      S = NewString (S);
  1107.       }
  1108.       semaphore_signal (SRefSemaphore);
  1109.       return S;
  1110.    }
  1111.  
  1112. /*
  1113.  * InitString
  1114.  *
  1115.  * Initialize this module
  1116.  */
  1117. void InitString ()
  1118.    {
  1119.       int C; 
  1120.       StrPtr S;
  1121.  
  1122.       CharString = (StrPtr *) malloc (128 * sizeof (StrPtr));
  1123.       CharString [0] = NULL;
  1124.       for (C = 1; C<128; C++) {
  1125.      CharString [C] = S = NewSCell ();
  1126.      S->StrChar [0] = C;
  1127.      S->StrChar [1] = '\0';
  1128.       }
  1129.    }
  1130.  
  1131. /************************** end of string.c **************************/
  1132.  
  1133. SHAR_EOF
  1134. if test -f 'interp/string.h'
  1135. then
  1136.     echo shar: over-writing existing file "'interp/string.h'"
  1137. fi
  1138. cat << \SHAR_EOF > 'interp/string.h'
  1139.  
  1140. /****** string.h ******************************************************/
  1141. /**                                                                  **/
  1142. /**                    University of Illinois                        **/
  1143. /**                                                                  **/
  1144. /**                Department of Computer Science                    **/
  1145. /**                                                                  **/
  1146. /**   Tool: IFP                         Version: 0.5                 **/
  1147. /**                                                                  **/
  1148. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1149. /**                                                                  **/
  1150. /**   Revised by: Arch D. Robison       Date:  Jan 20, 1987          **/
  1151. /**                                                                  **/
  1152. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1153. /**                            Prof. W. J. Kubitz                    **/
  1154. /**                                                                  **/
  1155. /**                                                                  **/
  1156. /**------------------------------------------------------------------**/
  1157. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1158. /**                       All Rights Reserved.                       **/
  1159. /**********************************************************************/
  1160.  
  1161. /*
  1162.  * CharPtr
  1163.  *
  1164.  * Character pointer
  1165.  *
  1166.  * Character pointers are for an IFP string what file pointers are
  1167.  * for a UNIX file.  Character pointers are used for both creating
  1168.  * (writing) and scanning (reading) IFP strings.  The structure of
  1169.  * IFP strings (type String) is described in struct.h.
  1170.  */
  1171. typedef struct {
  1172.    int CPCount;    /* number of characters left in current segment */
  1173.    char *CPChar;   /* pointer to current character */
  1174.    StrPtr *CPStr;  /* pointer to root of string */
  1175.    StrPtr CPSeg;   /* pointer to current segment of string */
  1176. } CharPtr;
  1177.  
  1178. extern StrPtr *CharString;        /* from string.c */
  1179. extern StrPtr MakeString ();
  1180. extern void DelSPtr ();     
  1181. extern StrPtr CopySPtr (); 
  1182. extern void CPInit (), CPAppend ();
  1183. extern boolean CPRead ();
  1184. extern FPint LenStr ();
  1185.  
  1186. /************************* end of string.h *************************/
  1187.  
  1188. SHAR_EOF
  1189. if test -f 'interp/struct.h'
  1190. then
  1191.     echo shar: over-writing existing file "'interp/struct.h'"
  1192. fi
  1193. cat << \SHAR_EOF > 'interp/struct.h'
  1194.  
  1195. /****** struct.h ******************************************************/
  1196. /**                                                                  **/
  1197. /**                    University of Illinois                        **/
  1198. /**                                                                  **/
  1199. /**                Department of Computer Science                    **/
  1200. /**                                                                  **/
  1201. /**   Tool: IFP                         Version: 0.5                 **/
  1202. /**                                                                  **/
  1203. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1204. /**                                                                  **/
  1205. /**   Revised by: Arch D. Robison       Date:   Aug 4, 1986          **/
  1206. /**                                                                  **/
  1207. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1208. /**                            Prof. W. J. Kubitz                    **/
  1209. /**                                                                  **/
  1210. /**                                                                  **/
  1211. /**------------------------------------------------------------------**/
  1212. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1213. /**                       All Rights Reserved.                       **/
  1214. /**********************************************************************/
  1215.  
  1216. /*
  1217.  * There are some preprocessor variables which must be defined either
  1218.  * here or in the cc command.  The following options are not available
  1219.  * in the public domain release:
  1220.  *
  1221.  *     ARRAYS, COMPILE, UMAX, VECTOR, OUTBERKELEY
  1222.  *
  1223.  * Some of the code for these options are removed from the source by 
  1224.  * unifdef(1), so the source may look strange in places.  (E.g. degenerate 
  1225.  * switch statements).
  1226.  *
  1227.  * The preprocessor variables are listed below.
  1228.  *
  1229.  * OPSYS (UNIX, MSDOS, CTSS) - specifies operating system
  1230.  * PCAT - for compiling on PC/ATs
  1231.  * SQUEEZE - put space at a premium
  1232.  * DEBUG - incorporate interpreter debugging spy points
  1233.  * DUMP - incoporate dump command for debugging (see debug.c)
  1234.  * REFCHECK - incorporate reference checking command (see apply.c)
  1235.  * COMPILE - incorporate IFP compiler (see C_comp.h)
  1236.  * ARRAYS - incorporate array representation of sequences
  1237.  * VECTOR - define APL-style vector operations (must define ARRAYS also)
  1238.  * UMAX - make parallel version for Encore Multimax
  1239.  *
  1240.  * There are also preprocessor variables which may be turned on or off
  1241.  * in the following files:
  1242.  *
  1243.  *      ECACHE in cache.h - implement expression cache
  1244.  *      STATS in stats.h - collect run time statistics
  1245.  *      FETCH in node.h - implement "fetch" functional form
  1246.  *    OUTBERKELEY in outberkely.h - implement routine to print functions in
  1247.  *                      Berkeley FP format.
  1248.  *
  1249.  * WARNING: Some of the compiling options may interfere with each other.
  1250.  *          Some options have not been tested for many revisions, so
  1251.  *        new bugs may creep out of the woodwork!
  1252.  */
  1253.  
  1254. #define UMAX 0        /* Must not enable ARRAYS, ECACHE, or STATS if set */
  1255. #define DUMP 0
  1256. #define ARRAYS 0    /* Must also define VECTOR=1 if set */
  1257. #define VECTOR 0
  1258. #define DEBUG 0
  1259. #define REFCHECK 0
  1260.  
  1261. /*
  1262.  * Possible values for OPSYS preprocessor variable.
  1263.  */
  1264. #define UNIX  10
  1265. #define MSDOS 11
  1266. #define CTSS  12
  1267.  
  1268. #define OPSYS UNIX
  1269.  
  1270. #if OPSYS==CTSS
  1271. /*
  1272.  * PARAMBUG is defined to indicate that the C compiler can not
  1273.  * take the address (&) of parameter variables correctly.
  1274.  * When this bug is removed from the CRAY C compiler, this define
  1275.  * and dependent code should be removed.
  1276.  */
  1277. #define PARAMBUG 1
  1278. #endif
  1279.  
  1280. #if OPSYS==MSDOS || OPSYS==CTSS 
  1281. #define MAXPATH 65     /* Maximum pathname length allowed (in characters) */
  1282. #endif
  1283.  
  1284. #if OPSYS==UNIX
  1285. #define MAXPATH 256    /* Maximum pathname length allowed (in characters) */
  1286. #endif
  1287.  
  1288. #if OPSYS==CTSS
  1289. #define index strchr
  1290. #endif
  1291.  
  1292. #ifdef PCAT
  1293. #define index strchr
  1294. #endif
  1295.  
  1296. /********** Fundamental Data Structures and Constants **********/
  1297.  
  1298.  
  1299. #define private static
  1300. #define forward extern  /* for forward definitions which are not external */
  1301. typedef int boolean;
  1302. typedef long FPint;
  1303. typedef int FPboolean;
  1304.  
  1305. typedef short ushort;
  1306.  
  1307. /********************** MACHINE DEPENDENT CONSTANTS **********************/
  1308.  
  1309. /* These two definitions assume two's complement arithmetic! */
  1310. #define FPMaxInt (((FPint) 1 << 8 * sizeof(FPint) - 1) - 1)
  1311. #define MaxInt   (((  int) 1 << 8 * sizeof(  int) - 1) - 1)
  1312.  
  1313. #ifdef SQUEEZE
  1314.  
  1315. /* Maximum floating point value representable by an FPfloat */
  1316. typedef float FPfloat;
  1317.  
  1318. #define MAXFLOAT 1e38
  1319. #define LNMAXFLOAT 88.7
  1320.  
  1321. #define CompTol (1e-6)
  1322.  
  1323. #else
  1324.  
  1325. typedef double FPfloat;
  1326.  
  1327. /* Maximum floating point value representable by an FPfloat */
  1328. #define MAXFLOAT 1.8e308
  1329. #define LNMAXFLOAT 710.37     /* ln (MAXFLOAT) */
  1330.  
  1331. #define CompTol (1e-8)
  1332.  
  1333. #endif
  1334.  
  1335. /* if abs(A),abs(B) are both < MAXFACTOR then A*B will fit in FPInt */
  1336. #define MAXFACTOR 0xB504L
  1337.  
  1338. /****************** end of machine dependent constants *********************/
  1339.  
  1340. /********************************* Strings *********************************/
  1341.  
  1342. /*
  1343.  * StrCell
  1344.  *
  1345.  * Each string is segmented into a linked list.  The first record of the
  1346.  * linked list contains the reference count for the string.
  1347.  * The string is terminated by a segment with a null StrNext field or
  1348.  * a '\0', whichever comes first.  The empty string is represented
  1349.  * by a null pointer.  Segments have '\0' as their first character iff
  1350.  * they are in the free string list.
  1351.  */
  1352.  
  1353. /*
  1354.  * StrHeadLen is the maximum number of characters which can be contained in
  1355.  * the first segment of a string list.  
  1356.  */
  1357. #if OPSYS==CTSS
  1358. #define StrHeadLen 8    /* For 64-bit ushort and 64-bit pointer */
  1359. #else 
  1360. #define StrHeadLen 10    /* For 16-bit ushort and 32-bit pointer */
  1361. #endif
  1362.  
  1363. #define StrTailLen (StrHeadLen + sizeof (ushort))
  1364.  
  1365. typedef struct StrCell {
  1366.    struct StrCell *StrNext;
  1367.    union {
  1368.       char StrVar1 [StrTailLen];
  1369.       struct {
  1370.      char StrV1F1 [StrHeadLen];
  1371.      ushort StrV1F2;
  1372.       } StrVar2;
  1373.    } StrUni1;
  1374. } StrCell;
  1375.  
  1376. typedef StrCell *StrPtr;
  1377.  
  1378. #define StrChar StrUni1.StrVar1
  1379. #define SRef StrUni1.StrVar2.StrV1F2
  1380.  
  1381. /****************************** Sequences ******************************/
  1382.  
  1383. /*
  1384.  * Sequences are guaranteed not to have cycles by the definition of FP.
  1385.  * Note that function representation lists may have a cycle, but the cycle
  1386.  * will always contain a function name as a member.  Cycle will be broken
  1387.  * when the function definition is deleted.
  1388.  */
  1389.  
  1390. /* Object Tags */
  1391. #define BOTTOM  0
  1392. #define BOOLEAN 1
  1393. #define INT     2
  1394. #define FLOAT   3
  1395. #define LIST    4
  1396. #define STRING  5
  1397. #define NODE    6
  1398. #define CODE    7
  1399. #define JOIN    8
  1400.  
  1401. /* Bitmasks for PairTest */
  1402. #define NUMERIC ((1<<FLOAT)|(1<<INT))
  1403. #define ATOMIC (NUMERIC | (1<<BOOLEAN) | (1<<STRING))
  1404.  
  1405.  
  1406. #define MAXTAG  7
  1407. #define SEQUENCE (1<<LIST)
  1408.  
  1409.  
  1410. /* Tag checking expressions dependent upon tag value assignments above */
  1411. #define Scalar(Tag) ((Tag) < 4)
  1412. #define Numeric(Tag) (((Tag)&~1)^2==0)
  1413. #define NotNumPair(Tag1,Tag2) ((((Tag1)^2)|((Tag2)^2))&~1) 
  1414. #define IntPair(Tag1,Tag2) ((Tag1+Tag2) == 4)
  1415.  
  1416. typedef struct CodeCell {
  1417.    int (*CodePtr) ();           /* (*CodePtr) (InOut,CodeParam) */
  1418.    int CodeParam;
  1419. } CodeCell;
  1420.  
  1421. typedef union {
  1422.    FPfloat _Float;
  1423.    FPint _Int;
  1424.    FPboolean _Bool;
  1425.    struct ListCell *_List;
  1426.    StrPtr _String;
  1427.    struct NodeDesc *_Node;
  1428.    CodeCell _Code;
  1429. } ObUnion;              
  1430.  
  1431. #define Float Data._Float
  1432. #define Int Data._Int
  1433. #define Bool Data._Bool
  1434. #define List Data._List
  1435. #define String Data._String
  1436. #define Node Data._Node
  1437. #define Code Data._Code
  1438.  
  1439. /*
  1440.  * Note on ARRAYS structures.  Cells with the ARRAY tag use the List field
  1441.  * to point to an array descriptor list.  The first element of the list
  1442.  * uses the APtr field, subsequent elements use the ADim field.
  1443.  */
  1444.  
  1445. /*
  1446.  * Object 
  1447.  *
  1448.  * An Object is a union which stores an IFP object.  The _LRef field is not 
  1449.  * logically part of an * object, but rather part of a ListCell.  We get much 
  1450.  * better packing by including it in Object, since it fits in a 32-bit word 
  1451.  * along with the Tag field.
  1452.  *
  1453.  * Likewise, for the UMAX version the _LRefLock field is physically part
  1454.  * of Object though it should be part of ListCell.
  1455.  *
  1456.  * Note that P->Val = Q->Val will transfer the reference count!
  1457.  */  
  1458. typedef struct {
  1459.    ObUnion Data;
  1460.    ushort _LRef;
  1461.    char Tag;   /* BOTTOM,BOOLEAN,INT,FLOAT,LIST,STRING,NODE,CODE,ARRAY */
  1462. } Object;
  1463.  
  1464. /*
  1465.  * ListCell
  1466.  *
  1467.  * Sequences are represented as linked lists of objects.  Each ListCell
  1468.  * also contains a reference count (hidden in the Object field).  The
  1469.  * value stored in the reference count is offset by -1.  The rationale is
  1470.  * that reference counts are always compared against one, and comparing
  1471.  * against zero is faster on some machines.  
  1472.  */ 
  1473. typedef struct ListCell {
  1474.    Object Val;            /* Value of first element of sequence (CAR) */
  1475.    struct ListCell *Next;    /* Pointer tail of sequence (CDR)         */
  1476. } ListCell;
  1477.  
  1478. #define LRef Val._LRef
  1479. #define LRefOne 0           /* value of LRef for reference count of 1 */
  1480.  
  1481.  
  1482. /*
  1483.  * Most of the code uses subsets of the alphabet for certain types.
  1484.  * For example, P,Q, and R are usually ListPtr.
  1485.  */
  1486. typedef ListCell *ListPtr;    /* e.g. P,Q,R */
  1487. typedef ListPtr *MetaPtr;    /* e.g. A,B,C */
  1488. typedef Object *ObjectPtr;    /* e.g. X,Y,Z */
  1489.  
  1490. #define NIL ((ListPtr) NULL)    /* empty list */
  1491.  
  1492. /******************************* Definitions ******************************/
  1493.  
  1494. /*
  1495.  * DefDesc
  1496.  *
  1497.  * DefFlags = subset of {TRACE,RESOLVED}.
  1498.  * DefCode = code for definition - BOTTOM if not resident.
  1499.  */
  1500. typedef struct DefDesc {
  1501.    char DefFlags;
  1502.    Object DefCode;
  1503. } DefDesc;
  1504.  
  1505. typedef DefDesc *DefPtr;
  1506.  
  1507. #define TRACE  1       /* Print input and output.                      */
  1508. #define RESOLVED 4     /* Mark bit used by reference checker           */
  1509.  
  1510. /*
  1511.  * All compiled FP functions have the following form:
  1512.  *
  1513.  *   void F (InOut,CodeParam)
  1514.  *      ObjectPtr InOut;
  1515.  *      int CodeParam;
  1516.  *      {...};
  1517.  *
  1518.  * F replaces *InOut with the result of applying F to *InOut.
  1519.  * CodeParam  is optional.
  1520.  */
  1521.  
  1522.  
  1523. /******************************* Modules *******************************/
  1524.  
  1525. /*
  1526.  * Modules are stored as lists of nodes.  Each node has a pointer to
  1527.  * its next sibling and its parent node.
  1528.  */
  1529. typedef struct {                /* Module node descriptor */
  1530.    struct NodeDesc *FirstChild;
  1531. } ModDesc;
  1532.  
  1533. /******************************** Imports ******************************/
  1534.  
  1535. /*
  1536.  * Definition nodes are imported with IMPORT nodes.  An import node in a
  1537.  * module points to a definition node elsewhere.
  1538.  */
  1539. typedef struct {
  1540.    Object ImpDef;     /* Can be path list or node */
  1541. } ImpDesc;
  1542.  
  1543. /******************************** Nodes ********************************/
  1544.  
  1545. #define NEWNODE 0 /* Values for NodeType */
  1546. #define MODULE 1
  1547. #define DEF 2
  1548. #define IMPORT 3
  1549.  
  1550. /*
  1551.  * NodeDesc
  1552.  *
  1553.  * See the top of node.c for the description of how these are linked together
  1554.  * to form the function/module tree.
  1555.  *
  1556.  * NRef = reference count (references by objects)
  1557.  * NodeNext = pointer to next sibling (or parent).
  1558.  * NodeType = type of node (DEF, MODULE, IMPORT)
  1559.  * NodeName = print name of node.
  1560.  */
  1561. typedef union {
  1562.    DefDesc NodeDef;     /* if DEF    */
  1563.    ModDesc NodeMod;     /* if MODULE */
  1564.    ImpDesc NodeImp;     /* if IMPORT */
  1565. } NDunion;
  1566.  
  1567. typedef struct NodeDesc {
  1568.    struct NodeDesc *NodeSib;
  1569.    struct NodeDesc *NodeParent;
  1570.    StrPtr NodeName;
  1571.    short NRef;
  1572.    char NodeType;
  1573.    NDunion NodeData;
  1574. } NodeDesc;
  1575.  
  1576. typedef struct NodeDesc *NodePtr;
  1577.  
  1578. /*----------------- exception handling: see except.c -----------------*/
  1579.  
  1580. /* values for SysError, 0 == no error */
  1581.  
  1582. #define INTERNAL     1     /* Inexplicable internal error  */
  1583. #define NO_LIST_FREE 2       /* Ran out of list cell storage */
  1584. #define NO_STR_FREE  3       /*  "   "  " string  "     "    */
  1585. #define NO_NODE_FREE 4       /*  "   "  "  node   "      "   */
  1586.  
  1587. extern short SysError;     /* An error occurred if SysError != 0 */
  1588. extern short SysStop;      /* Stop evaluation if != 0            */
  1589.  
  1590. /*------------ debugging the interpreter: see debug.c ----------------*/
  1591.  
  1592. /*
  1593.  * The interpreter may be compiled with internal spy points.  These spy 
  1594.  * points print internal information on stdout.  To include the spy * points, 
  1595.  * the interpreter must be compiled with #define DEBUG 1.  To turn on a spy 
  1596.  * point when running ifp, use the command line option '-d' followed by the 
  1597.  * appropriate letters.  The letters are defined by ``DebugOpt'' below.  
  1598.  * For example,
  1599.  *
  1600.  *    ifp -dar
  1601.  *
  1602.  * will turn on spy points related to memory allocation (a) and 
  1603.  * reference counts (r).
  1604.  */
  1605. #define DebugParse       (1<<0)    /* parser        */
  1606. #define DebugAlloc     (1<<1)    /* memory allocation     */
  1607. #define DebugFile    (1<<2)    /* file io         */
  1608. #define DebugRef    (1<<3)    /* reference counts     */
  1609. #define DebugInit    (1<<4)    /* initialization    */
  1610. #define DebugCache    (1<<5)    /* expression cache    */
  1611. #define DebugXDef    (1<<6)    /* extended definitions */
  1612. #define DebugHyper    (1<<7)    /* hypercube        */
  1613. #define DebugUMax    (1<<8)  /* multimax        */
  1614. #define DebugSemaphore  (1<<9)  /* semaphores        */
  1615. #define DebugFreeList   (1<<10) /* free list        */
  1616. #define DebugExpQueue   (1<<11) /* expression queue    */
  1617.  
  1618. #define DebugOpt "pafricxhusle"    /* option letters for above */
  1619.  
  1620. #if DEBUG
  1621. extern int Debug;    /* Bit-set of enabled spy points */
  1622. #else
  1623. #define Debug 0        /* Turn spy points into dead code */
  1624. #endif
  1625.  
  1626. /*--------------------------------------------------------------------*/
  1627.  
  1628. extern NodePtr CurWorkDir;     /* Current working directory */
  1629. extern NodePtr SysDef ();
  1630.  
  1631. extern void DelLPtr ();         /* Delete a list pointer */
  1632. extern ListPtr CopyLPtr ();     /* Copy a list pointer */
  1633.  
  1634. extern void Rot3 ();            /* list pointer rotation */
  1635.  
  1636. extern long ListLength ();              /* from list.c */
  1637. extern void CopyObject ();
  1638. extern ListPtr Repeat ();
  1639. extern void NewList ();
  1640. extern void RepTag ();
  1641. extern boolean RepObject ();
  1642. extern void RepLPtr ();
  1643. extern void CopyTop ();
  1644. extern void Copy2Top ();
  1645. extern void RepBool ();
  1646.  
  1647. extern void Apply ();                   /* from apply.c */
  1648. extern NodePtr ApplyFun;
  1649.  
  1650. extern void NodeExpand ();
  1651.  
  1652. extern void ExecEdit (), ReadImport (); /* from file.c */
  1653.  
  1654. extern void OutObject (), OutList ();   /* from outob.c */
  1655. extern void OutString (), OutNode ();
  1656. extern void OutForm (), OutFun ();      /* from outfun.c */
  1657. extern void OutPretty ();
  1658.  
  1659. extern void InitIn (), InBlanks ();    /* from inob.c */
  1660.  
  1661. extern void ReadDef (), DelImport ();
  1662. extern void InImport (); 
  1663.  
  1664. extern int InError();            /* from error.c */
  1665. extern void DefError (), IntError ();
  1666. extern void FunError (), FormError ();
  1667. extern char ArgNotSeq[], ArgObSeq[], ArgSeqOb[], ArgNull[], ArgBottom[];
  1668.  
  1669. extern NodePtr PrimDef ();
  1670. extern char *malloc();
  1671.  
  1672. #define ArrayEnd(A) (A+(sizeof(A)/sizeof A[0])) 
  1673.  
  1674.  
  1675. /************************** end of struct.h **************************/
  1676. SHAR_EOF
  1677. if test -f 'interp/trace.c'
  1678. then
  1679.     echo shar: over-writing existing file "'interp/trace.c'"
  1680. fi
  1681. cat << \SHAR_EOF > 'interp/trace.c'
  1682.  
  1683. /****** trace.c *******************************************************/
  1684. /**                                                                  **/
  1685. /**                    University of Illinois                        **/
  1686. /**                                                                  **/
  1687. /**                Department of Computer Science                    **/
  1688. /**                                                                  **/
  1689. /**   Tool: IFP                         Version: 0.5                 **/
  1690. /**                                                                  **/
  1691. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1692. /**                                                                  **/
  1693. /**   Revised by: Arch D. Robison       Date:  Sept 9, 1986          **/
  1694. /**                                                                  **/
  1695. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1696. /**                            Prof. W. J. Kubitz                    **/
  1697. /**                                                                  **/
  1698. /**                                                                  **/
  1699. /**------------------------------------------------------------------**/
  1700. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1701. /**                       All Rights Reserved.                       **/
  1702. /**********************************************************************/
  1703.  
  1704. #include <stdio.h>
  1705. #include "struct.h"
  1706. #include "umax.h"
  1707.  
  1708. int TraceIndent = 0;    /* Indentation level of trace         */
  1709. int TraceDepth = 2;    /* Depth to which functions are printed */
  1710.  
  1711. /*
  1712.  * PrintTrace
  1713.  *
  1714.  * Print a trace messages "ENTER>" or "EXIT> " with their arguments.
  1715.  * Each message is preceeded by an indentation pattern.  Each '|' in
  1716.  * the pattern represents one level of indentation; each '.' in the
  1717.  * patttern represents DOTSIZE levels of indentation.  The latter
  1718.  * abbreviation keeps us from going off the deep end.
  1719.  */
  1720. #define DOTSIZE 20
  1721.  
  1722. void PrintTrace (F,InOut,EnterExit)
  1723.    ObjectPtr F,InOut;
  1724.    char *EnterExit;
  1725.    {
  1726.       int K;
  1727.  
  1728.       /*
  1729.        * A SysStop >= 2 indicates multiple user interrupts, i.e. the user
  1730.        * does not want to see trace information.
  1731.        */
  1732.       if (SysStop < 2) {
  1733.      LineWait ();
  1734.      for (K = TraceIndent; K>=DOTSIZE; K-=DOTSIZE) printf (".");
  1735.      while (--K >= 0) printf (" |");
  1736.      printf (EnterExit);
  1737.      OutObject (InOut);
  1738.      printf (" : ");
  1739.      OutFun (F,TraceDepth);
  1740.      printf ("\n");
  1741.      LineSignal ();
  1742.       }
  1743.    }
  1744.  
  1745. /******************************* end of trace.c ******************************/
  1746.  
  1747. SHAR_EOF
  1748. if test -f 'interp/umax.h'
  1749. then
  1750.     echo shar: over-writing existing file "'interp/umax.h'"
  1751. fi
  1752. cat << \SHAR_EOF > 'interp/umax.h'
  1753.  
  1754. /****** umax.h *******************************************************/
  1755. /**                                                                  **/
  1756. /**                    University of Illinois                        **/
  1757. /**                                                                  **/
  1758. /**                Department of Computer Science                    **/
  1759. /**                                                                  **/
  1760. /**   Tool: IFP                         Version: 0.5                 **/
  1761. /**                                                                  **/
  1762. /**   Author:  Arch D. Robison          Date:   Nov 4, 1986          **/
  1763. /**                                                                  **/
  1764. /**   Revised by: Arch D. Robison       Date:  Jan 27, 1987          **/
  1765. /**                                                                  **/
  1766. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1767. /**                            Prof. W. J. Kubitz                    **/
  1768. /**                                                                  **/
  1769. /**                                                                  **/
  1770. /**------------------------------------------------------------------**/
  1771. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1772. /**                       All Rights Reserved.                       **/
  1773. /**********************************************************************/
  1774.  
  1775. /* 
  1776.  * Defining UMAX=1 in "struct.h" compiles the ifp interpreter for parallel
  1777.  * processing on the Multimax.
  1778.  */
  1779.  
  1780. #define semaphore_wait(s)
  1781. #define semaphore_signal(s)
  1782. #define rsemaphore_enter(r)
  1783. #define rsemaphore_exit(r)
  1784. #define spin_lock(s)
  1785. #define spin_unlock(s)
  1786. #define LineWait()
  1787. #define LineSignal()
  1788. #define Terminate()
  1789.  
  1790.  
  1791. /**************************** end of umax.h ****************************/
  1792. SHAR_EOF
  1793. if test -f 'interp/xdef.c'
  1794. then
  1795.     echo shar: over-writing existing file "'interp/xdef.c'"
  1796. fi
  1797. cat << \SHAR_EOF > 'interp/xdef.c'
  1798.  
  1799. /****** xdef.c ********************************************************/
  1800. /**                                                                  **/
  1801. /**                    University of Illinois                        **/
  1802. /**                                                                  **/
  1803. /**                Department of Computer Science                    **/
  1804. /**                                                                  **/
  1805. /**   Tool: IFP                         Version: 0.5                 **/
  1806. /**                                                                  **/
  1807. /**   Author:  Arch D. Robison          Date:   Aug 4, 1986          **/
  1808. /**                                                                  **/
  1809. /**   Revised by: Arch D. Robison       Date:   Aug 4, 1986          **/
  1810. /**                                                                  **/
  1811. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1812. /**                            Prof. W. J. Kubitz                    **/
  1813. /**                                                                  **/
  1814. /**                                                                  **/
  1815. /**------------------------------------------------------------------**/
  1816. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1817. /**                       All Rights Reserved.                       **/
  1818. /**********************************************************************/
  1819.  
  1820. /************************* Extended Definitions ************************/
  1821.  
  1822. #include <stdio.h>
  1823. #include "struct.h"
  1824. #include "node.h"
  1825. #include "inob.h"
  1826.  
  1827. #if XDEF
  1828.  
  1829. ListPtr Environment = NIL;
  1830.  
  1831. /*
  1832.  * OutLHS
  1833.  *
  1834.  * Input
  1835.  *      P = LHS to output
  1836.  */
  1837. void OutLHS (InOut)
  1838.    ObjectPtr InOut;
  1839.    {
  1840.       switch (InOut->Tag) {
  1841.      case LIST: {
  1842.         register ListPtr P=InOut->List;
  1843.         printf ("[");
  1844.         if (P!=NIL)
  1845.            while (1) {
  1846.           if (Debug & DebugRef) printf ("{%d}",P->LRef + (1 - LRefOne));
  1847.           OutLHS (& P->Val);
  1848.           if ((P=P->Next) == NULL) break; 
  1849.           else printf (",");
  1850.            }
  1851.         printf ("]");
  1852.         break;
  1853.      }
  1854.      default: OutObject (InOut);
  1855.       }
  1856.    }
  1857.  
  1858. /*
  1859.  * Assign
  1860.  *
  1861.  * Assign functional variables.
  1862.  *
  1863.  * Input
  1864.  *    X = object to be matched with LHS.
  1865.  *    F = LHS
  1866.  */
  1867. private boolean Assign (X,F)
  1868.    ObjectPtr X,F;
  1869.    {
  1870.       register ListPtr P,Q;
  1871.       extern StrPtr CopySPtr();
  1872.  
  1873.       switch (F->Tag) {
  1874.  
  1875.      case STRING:
  1876.         NewList (&Environment,2L);
  1877.         P = Environment;
  1878.         P->Val.Tag = STRING;
  1879.         P->Val.String = CopySPtr (F->String);
  1880.         CopyObject (&P->Next->Val,X);
  1881.         return 1;
  1882.  
  1883.      case LIST:
  1884.         if (X->Tag != LIST) return 0;
  1885.         else {
  1886.            for (Q=X->List,P=F->List; P!=NULL; Q=Q->Next,P=P->Next) 
  1887.           if (Q==NULL || !Assign (&Q->Val,&P->Val)) return 0;
  1888.            return 1;
  1889.         }
  1890.  
  1891.      default: 
  1892.         return 0;
  1893.       } 
  1894.    }
  1895.  
  1896. /*
  1897.  * FF_XDef
  1898.  *
  1899.  * Apply function F to each element of list InOut
  1900.  *
  1901.  * Input
  1902.  *      InOut = list of elements to apply function
  1903.  *      Funs = <lhs rhs function>
  1904.  *
  1905.  * Output
  1906.  *      InOut = result
  1907.  */
  1908. FF_XDef (InOut,Funs)
  1909.    ObjectPtr InOut;
  1910.    register ListPtr Funs;
  1911.    {
  1912.       ListPtr P;
  1913.       Object X;
  1914.       boolean InRange;
  1915.  
  1916.       if (3L != ListLength (Funs)) {
  1917.      FormError (InOut,"invalid xdef",NULL,Funs);
  1918.      return;
  1919.       }
  1920.       CopyObject (&X,InOut);
  1921.       Apply (&X,&Funs->Next->Val);
  1922.       P = Environment;
  1923.       InRange = Assign (&X,&Funs->Val);
  1924.       RepTag (&X,BOTTOM);
  1925.       if (InRange) 
  1926.      Apply (InOut,&Funs->Next->Next->Val);
  1927.       else if (PrintErr (InOut)) {
  1928.      OutLHS (&Funs->Val);
  1929.      printf (": domain error\n");
  1930.      OutObject (InOut);
  1931.      printf ("\n");
  1932.      RepTag (InOut,BOTTOM);
  1933.       }
  1934.       RepLPtr (&Environment,P);
  1935.    }
  1936.  
  1937. /*
  1938.  * InLHSC
  1939.  * 
  1940.  * Input
  1941.  *     F = input descriptor pointing to '['
  1942.  *
  1943.  * Output
  1944.  *     result = true iff no error occurs
  1945.  *     *X = sequence, or unchanged if error occurs.
  1946.  */
  1947. private boolean InLHSC (F,X,Env)
  1948.    register InDesc *F;
  1949.    ObjectPtr X;
  1950.    ListPtr *Env;
  1951.    {
  1952.       register MetaPtr A;
  1953.       ListPtr R;
  1954.  
  1955.       *(A = &R) = NULL;
  1956.       F->InPtr++; 
  1957.       InBlanks (F);
  1958.   
  1959.       while (']' != *F->InPtr) {
  1960.      if (!*F->InPtr) {
  1961.         DelLPtr (R);
  1962.         return InError (F,"unfinished construction");
  1963.      }
  1964.      NewList (A,1L);
  1965.      if (SysError || !InLHS (F,&(*A)->Val,Env)) {
  1966.         DelLPtr (R);
  1967.         return 0;
  1968.      }
  1969.      A = & (*A)->Next;
  1970.      if (*F->InPtr == ',') {
  1971.         F->InPtr++;
  1972.         InBlanks (F);
  1973.      }
  1974.       }
  1975.       F->InPtr++;              /* Skip closing ']' */
  1976.       InBlanks (F);
  1977.       RepTag (X,LIST);
  1978.       X->List = R;
  1979.       return 1;
  1980.    }
  1981.  
  1982. /*
  1983.  * InLHS
  1984.  *
  1985.  * Read a left-hand-side of a functional variable definition.
  1986.  * Return true iff no error occurred.
  1987.  *
  1988.  * Input
  1989.  *      *F = input descriptor pointing to LHS
  1990.  *
  1991.  * Output
  1992.  *      *F = input descriptor pointing to next token
  1993.  *      *Lhs = left hand side    
  1994.  *    *Env = list of functional variables in LHS
  1995.  *
  1996.  * A SysError may occur, in which case X is unchanged.
  1997.  */
  1998. boolean InLHS (F,LHS,Env)
  1999.    register InDesc *F;
  2000.    register ObjectPtr LHS;
  2001.    ListPtr *Env;
  2002.    {
  2003.       register ListPtr P;
  2004.  
  2005.       if (Debug & DebugParse) printf ("InLHS: %s",F->InPtr);
  2006.       
  2007.       if (*F->InPtr == '[') return InLHSC (F,LHS,Env);
  2008.       else {
  2009.      if (NULL == InString (F,LHS,NodeDelim,0)) 
  2010.         return InError (F,"variable name expected");
  2011.      for (P= *Env; P!=NULL; P=P->Next)
  2012.         if (ObEqual (&P->Val,LHS)) 
  2013.            return InError (F,"redefinition of variable (to left of caret)");
  2014.      NewList (Env,1L);
  2015.      CopyObject (&(*Env)->Val,LHS);
  2016.      return 1;
  2017.       }
  2018.    }
  2019.  
  2020. #endif /* XDEF */
  2021.  
  2022. /******************************* end of xdef.c *******************************/
  2023.  
  2024. SHAR_EOF
  2025. #    End of shell archive
  2026. exit 0
  2027.  
  2028. -- 
  2029.  
  2030. Rich $alz            "Anger is an energy"
  2031. Cronus Project, BBN Labs    rsalz@pineapple.bbn.com
  2032. Moderator, comp.sources.unix    sources@uunet.uu.net
  2033.